<template>
  <div>
    <input
      multiple
      class="uploadFile"
      type="file"
      ref="fileInput"
      @change="uploadFile($event.target)"
      :accept="accept"
    />
    <div class="upload_pictures">
      <template v-if="!hasSlot">
        <div
          v-if="fileLists.length < maxNum"
          class="upload_btn"
          :class="{ bg_transparent: hasSlot }"
          @click="uploadFiless"
        >
          <i class="el-icon-plus"></i>
          <div class="upload_txt">上传文件</div>
        </div>
      </template>
      <div v-if="hasSlot" @click="uploadFiless">
        <slot></slot>
      </div>
      <div
        v-if="!hasSlot"
        class="view_img"
        v-for="(item, index) in fileLists"
        :key="index"
      >
        <el-image
          v-if="item.type == 1"
          class="view_img_url"
          :src="item.url"
          :preview-src-list="[item.url]"
        >
        </el-image>
        <div v-if="item.type == 2" class="video_box">
          <img
            class="video_img"
            src="@/assets/images/video_img.png"
            alt="加载失败"
          />
          <video-review
            class="video_box"
            ref="videoReview"
            :videoSrc="item.url"
          ></video-review>
        </div>
        <div
          @click="lookFiles(item.url)"
          v-if="item.type == 3 || item.type == 4"
          class="other_box"
        >
          <i class="el-icon-document"></i>
          <el-tooltip
            class="item"
            effect="dark"
            :content="item.name"
            placement="top"
          >
            <div class="other_text">
              <span>{{ item.name }}</span>
              {{
                item.name.slice(item.name.lastIndexOf("."), item.name.length)
              }}
            </div>
          </el-tooltip>
        </div>
        <img
          @click="delImg(index)"
          class="close_img"
          src="@/assets/images/close_img.png"
          alt="加载失败"
        />
      </div>
    </div>
  </div>
</template>

<script>
import { uploadOSS } from "@/api/upload";
import { getUniqueFileName } from "@/utils/util.js";
import videoReview from "@/components/videoReview/videoReview";

export default {
  props: {
    maxImageSize: {
      type: Number,
      default: 5, // 默认最大图片大小为5MB
    },
    maxVideoSize: {
      type: Number,
      default: 50, // 默认最大视频大小为50MB
    },
    type: {
      type: [Number, String],
      default: "", // 默认最大图片大小为5MB
    },
    hasSlot: {
      type: [Boolean],
      default: false, // 默认最大图片大小为5MB
    },
    accept: {
      type: [String],
      default: "*", // 默认最大图片大小为5MB
    },
    maxNum: {
      type: [String, Number],
      default: "3", // 默认最多图片为3张
    },
    echoFile: {
      type: Array,
      default: [], // 回显文件列表
    },
  },
  components: {
    videoReview,
  },
  watch: {
    echoFile: {
      handler(val) {
        this.fileLists = val;
      },
    },
  },
  created() {
    if (this.echoFile.length > 0) {
      this.fileLists = this.echoFile;
    }
  },
  data() {
    return {
      fileLists: [],
    };
  },
  methods: {
    lookFiles(url) {
      window.open(url);
    },
    uploadFiless() {
      if (this.fileLists.length == this.maxNum) {
        this.$modal.msgWarning(`上传文件个数最多为${this.maxNum}个！`);
        return;
      }
      const fileInput = this.$refs.fileInput;
      fileInput.click();
    },
    uploadFile(event) {
      let files = this.$refs.fileInput.files;
      for (let i = 0; i < files.length; i++) {
        let file = this.$refs.fileInput.files[i];
        const fileType = file.type.split("/")[0];
        console.log(fileType, "fileType");
        const fileSize = file.size / 1024 / 1024; // 转换为MB
        if (fileType === "image" && fileSize > this.maxImageSize) {
          this.$modal.msgWarning(`图片大小不能超过${this.maxImageSize}MB`);
          return;
        }
        if (fileType === "video" && fileSize > this.maxVideoSize) {
          this.$modal.msgWarning(`视频大小不能超过${this.maxVideoSize}MB`);
          return;
        }
        let mediaType = ["video", "image"];
        if (mediaType.indexOf(fileType) == -1 && fileSize > this.maxFileSize) {
          this.$modal.msgWarning(`文件大小不能超过${this.maxFileSize}MB`);
          return;
        }
      }
      this.uploadFiles(event, files);
      // 进行上传操作
    },
    async uploadFiles(event, files) {
      let imgTypes = [".png", ".jpg"];
      let videoTypes = [".mp4", ".webm"];
      let wordPdfPptTypes = [".pdf", ".doc", ".docx", ".pptx"];
      // 收集所有已存在的文件名（来自已上传 + 回显）
      const existingNames = this.echoFile.map((f) => f.name);
      const uploadPromises = Array.from(files).map(async (file) => {
        const uploadType = file.name.slice(
          file.name.lastIndexOf("."),
          file.name.length
        );
        let type;

        if (imgTypes.includes(uploadType.toLowerCase())) {
          type = 1;
        } else if (videoTypes.includes(uploadType.toLowerCase())) {
          type = 2;
        } else if (wordPdfPptTypes.includes(uploadType.toLowerCase())) {
          type = 3;
        } else {
          type = 4;
        }
        // 使用外部引入的重命名函数
        const uniqueFileName = getUniqueFileName(existingNames, file.name);
        // 创建重命名后的 File 对象
        const renamedFile = new File([file], uniqueFileName, {
          type: file.type,
        });
        let res;
        try {
          if (this.ossType) {
            const path = fammterString(this.ossType, this.uuid);
            res = await uploadOSS(renamedFile, path);
          } else {
            res = await uploadOSS(renamedFile);
          }
          // 上传成功，返回文件对象
          return {
            type,
            name: uniqueFileName,
            url: res[0], // 假设 res 是数组，取第一项
          };
        } catch (e) {
          console.error(`文件上传失败: ${uniqueFileName}`, e);
          // 可选：失败的文件是否仍保留在列表中？比如标记 error
          return {
            type,
            name: uniqueFileName,
            url: null,
            error: true,
          };
        }
      });

      try {
        // 等待所有上传完成
        const results = await Promise.all(uploadPromises);

        // 过滤掉上传失败且不需要显示的文件（可选）
        const successfulFiles = results.filter((item) => item.url); // 只保留成功上传的
        // 或者如果你想保留所有（包括失败的），直接用 results

        // 更新 fileLists
        this.fileLists.push(...successfulFiles); // 或者 results

        // 所有上传完成后再 emit
        this.$emit("uploadFiles", this.fileLists);
      } catch (e) {
        // 注意：Promise.all 一旦有一个 reject 就会走 catch
        // 如果你不希望失败一个就中断，上面的 try/catch 已经处理了每个文件，这里就不会报错
        // 所以上面每个 promise 内部捕获了错误，Promise.all 不会 reject
        console.error("批量上传过程中有文件失败", e);
        // 但由于每个错误已被单独处理，这里通常不会走到
      }
      this.$emit("uploadFiles", this.fileLists);
      //重置input
      event.value = "";
    },
    delImg(index) {
      this.fileLists.splice(index, 1);
      this.$emit("uploadFiles", this.fileLists);
    },
  },
};
</script>
<style lang="scss" scoped>
.uploadFile {
  display: none;
}
.upload_pictures {
  display: flex;
}
.upload_btn {
  width: 90px;
  height: 90px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #f5f5f5;
  cursor: pointer;
}
.bg_transparent {
  background: transparent !important;
}
.el-icon-plus {
  font-size: 18px;
  font-weight: bold;
  color: #999999;
}
.upload_txt {
  margin-top: 8px;
  font-size: 10px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.65);
  user-select: none;
}

.view_img {
  width: 90px;
  height: 90px;
  margin-left: 12px;
  position: relative;
}
.view_img_url {
  width: 100%;
  height: 100%;
}
.video_box {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f5f5f5;
  cursor: pointer;
}
.other_box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #f5f5f5;
  cursor: pointer;
  .el-icon-document {
    font-size: 18px;
    color: #565656;
  }
  .other_text {
    margin-top: 10px;
    font-size: 12px;
    color: #565656;
    display: flex;
    align-items: center;
    span {
      display: inline-block;
      width: 50px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}
.video_img {
  width: 24px;
  height: 24px;
  object-fit: cover;
  position: absolute;
}
.close_img {
  width: 16px;
  height: 16px;
  position: absolute;
  top: -4px;
  right: -4px;
  cursor: pointer;
}
</style>
